﻿using System.Net;
using System.Security;
using Honeycomb.Core;
using Honeycomb.Core.Client;
using Honeycomb.Core.Server;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Honeycomb.Test.ClientServerIntegration
{
    [TestClass]
    public class AuthenticationSpecification
    {
        class CustomAuthenticateHandler : AuthenticateHandler
        {
            // TODO: Username and passwords with uncommon characters not supported!!!
            public const string Username = "John Doe";
            public const string Password = "aseefffsdfsdfdsfs";

            public override bool Authenticate(NetworkCredential networkCredential)
            {
                return networkCredential.UserName == Username && networkCredential.Password == Password;
            }
        }

        [TestMethod]
        public void SupportsSuccessfulAnonymousAuthentication()
        {
            TestAuthentication(null, "", "", false);
        }

        [TestMethod]
        public void SupportsSuccessfulAuthentication()
        {
            TestAuthentication(new CustomAuthenticateHandler(), CustomAuthenticateHandler.Username, CustomAuthenticateHandler.Password, false);
        }

        [TestMethod]
        public void SupportsFailedAuthenticationIfPasswordIsInvalid()
        {
            TestAuthentication(new CustomAuthenticateHandler(), CustomAuthenticateHandler.Username, CustomAuthenticateHandler.Password + "a", true);
        }

        [TestMethod]
        public void SupportsFailedAuthenticationIfUsernameIsInvalid()
        {
            TestAuthentication(new CustomAuthenticateHandler(), CustomAuthenticateHandler.Username + "a", CustomAuthenticateHandler.Password, true);
        }

        [TestMethod]
        public void SupportsFailedAuthenticationIfUsernameAndPasswordIsInvalid()
        {
            TestAuthentication(new CustomAuthenticateHandler(), CustomAuthenticateHandler.Username + "a", CustomAuthenticateHandler.Password + "a", true);
        }

        private static void TestAuthentication(AuthenticateHandler authenticateHandler, string username, string password, bool expectSecurityException)
        {
            // Setup server.
            GridServer server = new GridServer();
            server.Start();
            if (authenticateHandler != null)
                server.AuthenticateHandler = authenticateHandler;

            // Setup client.
            SecurityException securityException = null;
            try
            {
                new GridClient(new GridUri("grid://" + username + ":" + password + "@localhost"));
            }
            catch (SecurityException ex)
            {
                securityException = ex;
            }

            server.Stop();

            Assert.IsTrue((securityException != null) == expectSecurityException);
        }
    }
}
